package rpcserver

import (
	"fmt"
	"gitee.com/jamon/espoir_go/common"
	"gitee.com/jamon/espoir_go/global"
	"gitee.com/jamon/espoir_go/logger"
	"gitee.com/jamon/espoir_go/route"
	"gitee.com/jamon/espoir_go/service"
)

// RequestHandler 客户端消息处理
type RequestHandler struct {
	nodeData   *global.NodeData
	serviceMgr *service.Manager
	routeCtl   *route.Controller
}

func NewRequestHandler() (handler *RequestHandler, err error) {
	handler = &RequestHandler{
		nodeData:   global.GetNodeData(),
		serviceMgr: service.GetManager(),
		routeCtl:   route.GetController(),
	}
	return
}

func (handler *RequestHandler) HandleMsg(req *common.MsgRequest, res *common.MsgResponse) (err error) {
	switch req.Type {
	case common.MsgType_REQUEST:
		err = handler.handleRequest(req, res)
	case common.MsgType_RESPONSE:
		err = handler.handleResponse(req, res)
	default:
		err = fmt.Errorf("unknown msg type: %v", req.Type)
	}
	res.MsgId = req.MsgId
	return
}

func (handler *RequestHandler) handleRequest(req *common.MsgRequest, res *common.MsgResponse) (err error) {
	defer func() {
		logger.Info("handleRequest: ", logger.Kwargs{"req": req, "res": res, "err": err})
	}()
	if req.To == handler.nodeData.Config.NodeID {
		// 本节点处理
		err = handler.serviceMgr.HandleRequest(req, res)
		return
	}

	if req.To != "" && req.To != handler.nodeData.Config.NodeID {
		// 不是本节点处理但有明确的目标节点，开始转发
		err = handler.routeCtl.RemoteServiceHandle(req, res)
		return
	}

	// 寻址
	routeGroupID, subAddress, err := handler.serviceMgr.GetRouteInfo(req)
	if err != nil {
		return
	}
	nodeID := handler.routeCtl.GetTargetNodeId(routeGroupID, subAddress)
	if nodeID == "" {
		return fmt.Errorf("no available node for routeGroupID: %v", routeGroupID)
	}
	req.To = nodeID
	err = handler.routeCtl.RemoteServiceHandle(req, res)

	return
}

func (handler *RequestHandler) handleResponse(req *common.MsgRequest, res *common.MsgResponse) (err error) {
	return
}
